package reserve
import (
    "time"
	"strings"
	"errors"
	"dhfshop/models"
	"github.com/astaxie/beego/orm"
)

// 预约单
type Reservation struct {
	ReservationId int64     `orm:"column(reservation_id);pk;auto" json:"reservation_id" form:"reservation_id"`
	PartnerId     int64       `orm:"column(partner_id)" json:"partner_id" form:"partner_id"`    
	StoreId       int64       `orm:"column(store_id)" json:"store_id" form:"store_id"`
	Schema        *Schema   `orm:"column(schema_id);rel(fk);on_delete(cascade)" json:"-" form:"-"` //级联删除
	SchemaId      int64     `orm:"-" json:"schema_id" form:"schema_id"`
    SchemaTypeId  int64     `orm:"-" json:"schema_type_id" form:"schema_type_id"` //
	Period        *Period   `orm:"column(period_id);rel(fk);on_delete(cascade)" json:"-" form:"-"`
	PeriodId      int64     `orm:"-" json:"period_id" form:"period_id"`
	Timeslot      *Timeslot `orm:"column(timeslot_id);rel(fk);on_delete(cascade)" json:"-" form:"-"` 
	TimeslotId    int64     `orm:"-" json:"timeslot_id" form:"timeslot_id"`
    MemberId      int64     `orm:"column(member_id)" json:"member_id" form:"member_id"` 
    SourceAt    time.Time   `orm:"column(source_at);type(date)" json:"-" form:"-"` //号源时间,只要日期到天
    SourceAtStr   string    `orm:"-" json:"source_at" form:"source_at"`
	Start         string    `orm:"column(start);null" json:"start" form:"start"`   //开始时间,非全日期时间,比如: 11:00
    End           string    `orm:"column(end);null" json:"end" form:"end"`         //结束时间,非全日期时间,比如: 12:00
	OrderSeq      int       `orm:"column(order_seq)" json:"order_seq" form:"order_seq"`                 //预约序号
	IsPayDeposit  bool      `orm:"column(is_pay_deposit);default(false)" json:"is_pay_deposit" form:"is_pay_deposit"`//是否支付定金
	Status        int       `orm:"column(status)" json:"status" form:"status"` 
	Note          string    `orm:"column(note);size(256);null" json:"note" form:"note"`                  //备注
	CreatedAt     time.Time `orm:"auto_now_add;column(created_at);type(datetime)" json:"created_at"`     //创建时间
	UpdatedAt     time.Time `orm:"auto_now;column(updated_at);type(datetime)" json:"-" form:"-"`         //修改时间
	// 非数据库字段
	FormId        string    `orm:"-" json:"-" form:"form_id"`         //为了发送通知，保存的form_id
}

type Location struct {
	LocationId int64     `orm:"column(location_id);pk;auto" json:"location_id" form:"-"` 
    PartnerId  int64     `orm:"column(partner_id)" json:"partner_id" form:"partner_id"` //商户ID
	Name       string  `orm:"column(name);size(128);null" json:"name" form:"name"` 
}

func init() {
	orm.RegisterModel(new(Reservation))
}

func ExistReservation(schemaId, periodId, memberId int64) bool {
    o := models.GetDefaultDB()
	qs := o.QueryTable(new(Reservation))
	qs = qs.Filter("schema_id", schemaId).Filter("period_id", periodId)
	if memberId > 0 {
	    qs = qs.Filter("member_id", memberId)
	}
	exist := qs.Exist()
	return exist
}

func AddReservation(m *Reservation) (id int64, err error) {
	o := models.GetDefaultDB()
	id, err = o.Insert(m)
	return
}

func AddMultiReservations(list []*Reservation) (err error) {
	size := len(list)
	o := models.GetDefaultDB()
	if size > 1 {
	    _, err = o.InsertMulti(size, list) 
	}else{
	   _, err = o.Insert(list[0])
	}
	return
}

func GetReservationById(id int64) (v *Reservation, err error) {
	o := models.GetDefaultDB()
	v = &Reservation{ReservationId: id}
	if err = o.Read(v); err == nil {
		return v, nil
	}
	return nil, err
}

func GetAllReservations(query map[string]string,fields []string,order_by map[string]string,offset int,limit int)([]*Reservation, int64,error) {
	o := models.GetDefaultDB()
	qs := o.QueryTable(new(Reservation))
	for k, v := range query {
		k = strings.Replace(k, ".", "__", -1)
		qs = qs.Filter(k, v)
	}
	cnt, err := qs.Count()
	var sortFields []string
	for k, v := range order_by {
		orderby := ""
		if v == "desc" {
			orderby = "-" + k
		} else if v == "asc" {
			orderby = k
		} else {
			return nil, 0, errors.New("Error: Invalid order. Must be either [asc|desc]")
		}
		sortFields = append(sortFields, orderby)
	}
	var lists []*Reservation
	qs = qs.OrderBy(sortFields...)
	if _, err := qs.Limit(limit, offset).All(&lists, fields...); err == nil {
		for _, reservation := range lists {
			reservation.SchemaId = reservation.Schema.SchemaId
			if schema, err := GetSchemaById(reservation.SchemaId); err == nil {
			    reservation.SchemaTypeId = schema.SchemaType.SchemaTypeId
			}
			reservation.PeriodId = reservation.Period.PeriodId
			reservation.TimeslotId = reservation.Timeslot.TimeslotId
			reservation.Schema = nil
			reservation.Period = nil
			reservation.Timeslot = nil
	    }
		return lists, cnt, nil
	}
	return nil, 0, err
}
func UpdateReservationById(m *Reservation, k ...string) (err error) {
	o := models.GetDefaultDB()
	v := Reservation{ReservationId: m.ReservationId}
	if err = o.Read(&v); err != nil {
		return err
	}else{
	    if _, err = o.Update(m, k...); err != nil {
		   return err
		}
	}
	return nil
}
func DeleteReservation(id int64) (err error) {
	o := models.GetDefaultDB()
	v := Reservation{ReservationId: id}
	if err = o.Read(&v); err == nil {
		if _, err = o.Delete(&v); err == nil {
			return nil
		}
	}
	return
}


//h, _:= time.ParseDuration("1m") 
//h, _:= time.ParseDuration("-1h")   
//sourceAt.Add(24*h)
func GetExpiringReservers(sourceAt time.Time, limit, offset int)([]*Reservation, error) {
	h, _:= time.ParseDuration("-1h")
	dstAt := sourceAt.Add(24*h)
	o := models.GetDefaultDB()
	qs := o.QueryTable(new(Reservation))
	qs = qs.Filter("agreed_at__gte", dstAt)
	var lists []*Reservation
	_, err := qs.Limit(limit, offset).All(&lists)
	if err == nil {
		return lists, nil
	}
	return nil, err
}

